package com.cfweb.api;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import javax.servlet.http.HttpSession;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.util.StreamUtils;

import com.cfweb.controller.LoginHandler;
import com.cfweb.domain.CfApp;
import com.cfweb.exception.CloudFoundryApiException;
import com.cfweb.pojo.OauthToken;
import com.cfweb.resouce.BuildResourceUtil;
import com.cfweb.util.CloudFoundryClientUtil;
import com.cfweb.util.JsonUtil;
import com.cfweb.util.MutiThreadUtil;
import com.cfweb.util.ResourceCall;
import com.cfweb.util.StringUtil;

/**
 * 
 * @author (minxianliu,yufangjiang) Dec 2, 2014
 */
public class ApplicationApi {
	/**
	 * cpu计算平均次数累计值
	 */
	private static final Integer STORE_LENGTH = 5;
	/**
	 * 存储计算cpu平均值的原始值
	 */
	private static Double[] avg = new Double[STORE_LENGTH];
	/**
	 * 迭代计数器
	 */
	private static int count;

	/**
	 * 检测cpu
	 * 
	 * @param session
	 * @param uuid
	 * @param index
	 * @param autoScale
	 * @param maxcpu
	 * @param mincpu
	 * @param maxinstance
	 * @param mininstance
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, Object> monitApp(HttpSession session, final String uuid, final int index,
			Short autoScale, Double maxcpu, Double mincpu, Integer maxinstance, Integer mininstance) throws Exception {
		Map<String, Object> data = null;
		try {
			String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
			String urlPath = host + "/v2/apps/" + uuid + "/stats";
			String content = CloudFoundryClientUtil.doCCGet(urlPath, null, session);
			//System.out.println("monitor:" + content);
			//System.out.println("index:" + index);
			Map<String, Object> stats = JsonUtil.convertJsonToMap(content);
			Integer instanceSize = stats.size();
			// 自动扩增
			if (autoScale == 1 && mincpu != null && maxcpu != null && maxinstance != null && mininstance != null) {
				Double pCpu = null;
				Double sum = 0.0;
				Map<String, Object> instanceFirst = (Map<String, Object>) ((Map<String, Object>) stats.get("0"))
						.get("stats");
				if (instanceFirst != null) {
					Map<String, Object> usage = (Map<String, Object>) instanceFirst.get("usage");
					count = count + 1;
					Double now = Double.valueOf(String.valueOf(usage.get("cpu"))) * 100;
					avg[count % 5] = now;
				}

				for (int i = 0; i < avg.length; i++) {
					if (avg[i] != null) {
						sum = sum + avg[i];
					}
				}

				if (avg.length > 0) {
					pCpu = sum / (avg.length);
				}

				if (pCpu != null && pCpu > 0) {
					Map<String, Object> params = new HashMap<String, Object>();
					if (pCpu > maxcpu && instanceSize < maxinstance) {
						params.put("instances", instanceSize + 1);
						ApplicationApi.updateApplication(uuid, params, session);
					}

					if (pCpu < mincpu && instanceSize > mininstance) {
						params.put("instances", instanceSize - 1);
						ApplicationApi.updateApplication(uuid, params, session);
					}
				}

			}
			
			if(stats.get(String.valueOf(index))==null){
				return null;
			}
			
			if(((Map<String, Object>) stats.get(String.valueOf(index))).get("stats")==null){
				return null;
			}
			
			data = (Map<String, Object>) ((Map<String, Object>) stats.get(String.valueOf(index))).get("stats");
		} catch (Exception e) {
			if (e instanceof CloudFoundryApiException && ((CloudFoundryApiException) e).getErrorCode() == 400) {
				return null;
			} else {
				throw e;
			}
		}
		return data;
	}

	/**
	 * get applications of the current session in general
	 * 
	 * @param session
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static List<Map<String, Object>> getApplications(HttpSession session) throws Exception {
		HttpClient httpClient = null;
		HttpGet httpGet = null;
		List<Map<String, Object>> results = new ArrayList<Map<String, Object>>();

		try {

			Long start1 = System.currentTimeMillis();
			String org = (String) session.getAttribute(LoginHandler.ORG);
			String space = (String) session.getAttribute(LoginHandler.SPACE);
			if (StringUtil.isEmpty(org) || StringUtil.isEmpty(space)) {
				return null;
			}
			String spaceGuid = UserApi.get_space_id(session, org, space);
			if (StringUtil.isEmpty(spaceGuid)) {
				return null;
			}
			String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
			String urlPath = host + "/v2/spaces/" + spaceGuid + "/apps?inline-relations-depth=1";
			httpClient = new DefaultHttpClient();
			httpGet = new HttpGet(urlPath);
			CloudFoundryClientUtil.setAccessHeaders(httpGet, session);
			HttpResponse response = httpClient.execute(httpGet);
			HttpEntity entity = response.getEntity();
			String content = EntityUtils.toString(entity, "UTF-8");
			Map<String, Object> data = JsonUtil.convertJsonToMap(content);
			List<Map<String, Object>> resources = (List<Map<String, Object>>) data.get("resources");
			String next_url = (String) data.get("next_url");
			while (next_url != null) {
				next_url = ApiCommonUtil.retriveAllPageResource(resources, next_url, session);
			}
			ThreadPoolExecutor exeThreads = MutiThreadUtil.getExecutorService();

			for (Map<String, Object> resource : resources) {
				List<Object> sbs = (List<Object>) ((Map<String, Object>) resource.get("entity"))
						.get("service_bindings");
				if (!(sbs != null && sbs.size() > 0)) {
					results.add(resource);
					continue;
				}
				StringBuffer sbf = new StringBuffer();
				for (Object sb : sbs) {
					String sbUrl = (String) ((Map<String, Object>) ((Map<String, Object>) sb).get("entity"))
							.get("service_instance_url");
					if (sbUrl != null && !"".equals(sbUrl)) {
						HttpClient hclient = new DefaultHttpClient();
						HttpGet hget = new HttpGet(host + sbUrl);
						CloudFoundryClientUtil.setAccessHeaders(hget, session);
						try {
							OauthToken token = (OauthToken) session.getAttribute(LoginHandler.TOKEN);
							Future<Map<String, Object>> res = exeThreads.submit(new ResourceCall(hclient, hget,
									ResourceCall.HTTP, ((URL) session.getAttribute(LoginHandler.TARGET)).toString(),
									token.getTokenType() + " " + token.getToken(session)));
							if (res != null) {
								sbf.append(((Map<String, Object>) res.get().get("entity")).get("name") + ",");
							}
						} catch (Exception e) {
							throw e;
						} finally {
							hget.abort();
							hclient.getConnectionManager().shutdown();
						}
					}
				}
				if (sbf != null && !"".equals(sbf.toString())) {
					resource.put("service_instance", sbf.toString());
				}
				results.add(resource);
			}
			Long end1 = System.currentTimeMillis();

			System.out.println("new method costed :" + (end1 - start1) + "ms");

		} catch (Exception e) {
			throw (e);
		} finally {
			if (httpGet != null) {
				httpGet.abort();
			}

			if (httpClient != null) {
				httpClient.getConnectionManager().shutdown();
			}
		}
		return results;
	}

	/**
	 * get buildPacks
	 * 
	 * @param session
	 * @return
	 * @throws Exception
	 */

	public static Map<String, Object> getBuildPacks(HttpSession session) throws Exception {
		Map<String, Object> data = null;
		try {
			String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
			String urlPath = host + "/v2/buildpacks";
			String content = CloudFoundryClientUtil.doCCGet(urlPath, null, session);
			data = JsonUtil.convertJsonToMap(content);
		} catch (Exception e) {
			throw (e);
		}
		return data;
	}

	/**
	 * restage the app to ensure that service can work on it
	 * 
	 * @param appUuidstringParams
	 * @param session
	 * @throws Exception
	 */
	public static boolean restageApp(String appUuid, HttpSession session) throws Exception {
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		String urlPath = host + "/v2/apps/" + appUuid + "/restage";
		CloudFoundryClientUtil.doCCPost(urlPath, null, session);
		return true;
	}

	/**
	 * 通過過濾所有apps獲取具體的app
	 * 
	 * @param session
	 * @param orgName
	 * @param spaceName
	 * @param appName
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static List<Map<String, Object>> getParticularApplicationBySpace(HttpSession session, String orgName,
			String spaceName, String appName) throws Exception {
		Map<String, Object> data = null;
		String spaceId = UserApi.get_space_id(session, orgName, spaceName);
		if (spaceId.isEmpty()) {
			return null;
		}
		try {
			String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
			String urlPath = host + "/v2/spaces/" + spaceId + "/apps?q=name:" + appName;
			String content = CloudFoundryClientUtil.doCCGet(urlPath, null, session);
			data = JsonUtil.convertJsonToMap(content);
			if ((int) data.get("total_results") == 0) {
				return null;
			}
		} catch (Exception e) {
			throw (e);
		}
		return (List<Map<String, Object>>) data.get("resources");
	}

	/**
	 * get apps by space
	 * 
	 * @param session
	 * @param orgName
	 * @param spaceName
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static List<Map<String, Object>> getApplicationBySpace(HttpSession session, String orgName, String spaceName)
			throws Exception {
		Map<String, Object> data = null;
		String spaceId = UserApi.get_space_id(session, orgName, spaceName);
		if (StringUtil.isEmpty(spaceId))
			return null;

		try {
			String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
			String urlPath = host + "/v2/spaces/" + spaceId + "/summary";
			String content = CloudFoundryClientUtil.doCCGet(urlPath, null, session);
			data = JsonUtil.convertJsonToMap(content);
		} catch (Exception e) {
			throw (e);
		}
		return (List<Map<String, Object>>) data.get("apps");
	}

	public static void updateApplicationUrls(String appGuid, String org, String space, List<String> urls,
			HttpSession session) throws Exception {
		List<String> routes = ApplicationApi.getAppRoutesList(appGuid, session);
		List<String> newUris = new ArrayList<String>(urls);
		newUris.removeAll(routes);
		List<String> removeUris = routes;
		removeUris.removeAll(urls);
		ApplicationApi.addAppRoute(appGuid, org, space, newUris, session);
		ApplicationApi.removeAppRoute(appGuid, org, space, removeUris, session);

	}

	/**
	 * 
	 * @param uuid
	 * @param params
	 * @param session
	 * @throws Exception
	 */
	public static void updateApplication(String uuid, Map<String, Object> params, HttpSession session) throws Exception {
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		String urlPath = host + "/v2/apps/" + uuid+"?async=true&inline-relations-depth=1";
		CloudFoundryClientUtil.doCCPut(urlPath, params, session);
	}

	/**
	 * 
	 * @param params
	 * @param session
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static String createApplication(Map<String, Object> params, HttpSession session) throws Exception {
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		//String host="http://api.local.lai";
		String urlPath = host + "/v2/apps";
		String content = CloudFoundryClientUtil.doCCPost(urlPath, params, session);
		Map<String, Object> data = JsonUtil.convertJsonToMap(content);
		Map<String, Object> metadata = (Map<String, Object>) data.get("metadata");
		return (String) metadata.get("guid");
	}

	/**
	 * 上传应用war包
	 * 
	 * @param app
	 * @param file
	 * @param session
	 * @throws Exception
	 */
	public static void uploadAppBit(CfApp app, File file, HttpSession session) throws Exception {
		ZipFile zipFile = new ZipFile(file);
		try{
			String resources = BuildResourceUtil.getResources(zipFile);
			String returnResouces = resource_match(resources, session);
			Map<String, Object> params = new HashMap<>();
			//String host ="http://api.local.lai";
			String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
			String urlPath = host + "/v2/apps/" + app.getUuid() + "/bits";
			params.put("file", file);
			params.put("name", app.getAppName());
			params.put("resources", returnResouces);
			CloudFoundryClientUtil.doCCPputWithFile(urlPath, params, session);
		}finally{			
			zipFile.close();
		}
	}

	/**
	 * 平台选择
	 * 
	 * @param name
	 * @param session
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static String getStackUUID(String name, HttpSession session) throws Exception {
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		String urlPath = host + "/v2/stacks";
		if (name != null) {
			urlPath = urlPath + "?q=name:" + name;
		}
		String content = CloudFoundryClientUtil.doCCGet(urlPath, null, session);
		Map<String, Object> data = JsonUtil.convertJsonToMap(content);
		List<Map<String, Object>> resources = (List<Map<String, Object>>) data.get("resources");
		if (resources.size() > 0) {
			return (String) ((Map<String, Object>) ((Map<String, Object>) resources.get(0)).get("metadata"))
					.get("guid");
		}
		return null;
	}

	/**
	 * 上传应用的resource_match
	 * 
	 * @param resource
	 * @param session
	 * @return
	 * @throws Exception
	 */
	public static String resource_match(String resource, HttpSession session) throws Exception {
		String host = ((URL)session.getAttribute(LoginHandler.TARGET)).toString();
		Map<String, Object> params = new HashMap<>();
		params.put("resources", resource);
		String urlPath = host + "/v2/resource_match";
		String content = CloudFoundryClientUtil.doResouceMatch(urlPath, params, session);
		return content;
	}

	/**
	 * 应用绑定服务
	 * 
	 * @throws Exception
	 */
	public static void bindService(String uuid, String serviceName, HttpSession session) throws Exception {
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		Map<String, Object> params = new HashMap<>();
		params.put("service_instance_guid", ServiceApi.getParticularServiceUUID(serviceName, session));
		params.put("app_guid", uuid);
		String urlPath = host + "/v2/service_bindings";
		CloudFoundryClientUtil.doCCPost(urlPath, params, session);
	}

	/**
	 * 应用解绑服务
	 * 
	 * @throws Exception
	 */
	public static void unbindService(String uuid, String serviceName, HttpSession session) throws Exception {
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		String urlPath = host + "/v2/apps/" + uuid + "/service_bindings/"
				+ getAppServiceBindingUUID(uuid, serviceName, session);
		CloudFoundryClientUtil.doCCDelete(urlPath, null, session);
	}

	/**
	 * 应用解绑服务
	 * 
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static String getAppServiceBindingUUID(String uuid, String serviceName, HttpSession session)
			throws Exception {
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		String SIID = ServiceApi.getParticularServiceUUID(serviceName, session);
		String urlPath = host + "/v2/apps/" + uuid + "/service_bindings?q=service_instance_guid:" + SIID;
		String content = CloudFoundryClientUtil.doCCGet(urlPath, null, session);
		Map<String, Object> data = JsonUtil.convertJsonToMap(content);
		List<Map<String, Object>> resources = (List<Map<String, Object>>) data.get("resources");
		if (resources.size() > 0) {
			return (String) ((Map<String, Object>) ((Map<String, Object>) resources.get(0)).get("metadata"))
					.get("guid");
		}
		return null;
	}

	/**
	 * 获取应用绑定服务
	 * 
	 * @param uuid
	 * @param session
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static List<Map<String, Object>> getAllAppService(String uuid, HttpSession session) throws Exception {
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		String urlPath = host + "/v2/apps/" + uuid + "/service_bindings";
		String content = CloudFoundryClientUtil.doCCGet(urlPath, null, session);
		Map<String, Object> data = JsonUtil.convertJsonToMap(content);
		List<Map<String, Object>> serviceBindings = (List<Map<String, Object>>) data.get("resources");
		String next_url = (String) data.get("next_url");
		while (next_url != null) {
			next_url = ApiCommonUtil.retriveAllPageResource(serviceBindings, next_url, session);
		}
		List<Map<String, Object>> response = new ArrayList<>();
		for (Map<String, Object> serbinding : serviceBindings) {
			Map<String, Object> entity = (Map<String, Object>) serbinding.get("entity");
			response.add(JsonUtil.convertJsonToMap(ServiceApi.getParticularService(
					(String) entity.get("service_instance_guid"), session)));
		}
		return response;
	}

	/**
	 * 获取应用服务
	 * 
	 * @param uuid
	 * @param session
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static List<String> getAllAppServiceName(String uuid, HttpSession session) throws Exception {
		Map<String, Object> appCl = ApplicationApi.getApp(uuid, session);
		List<Map<String, Object>> servicesRes = (List<Map<String, Object>>) appCl.get("services");
		List<String> services = new ArrayList<String>();
		for (Map<String, Object> sRes : servicesRes) {
			services.add((String) sRes.get("name"));
		}
		return services;
	}

	/**
	 * 停止应用instances
	 * 
	 * @param uuid
	 * @param session
	 * @throws Exception
	 */
	public static void stopApplication(String uuid, HttpSession session) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("state", "STOPPED");
		updateApplication(uuid, params, session);
	}

	/**
	 * 启动app
	 * 
	 * @param uuid
	 * @param session
	 * @throws Exception
	 */
	public static void startApplication(String uuid, HttpSession session) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("state", "STARTED");
		updateApplication(uuid, params, session);
	}
	
	/**
	 * 重启app
	 * 
	 * @param uuid
	 * @param session
	 * @throws Exception
	 */
	public static void restartApplication(String uuid, HttpSession session) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("state", "STOPPED");
		updateApplication(uuid, params, session);
		params.clear();
		params.put("state", "STARTED");
		updateApplication(uuid, params, session);
	}

	/**
	 * 更新环境变量
	 * 
	 * @param uuid
	 * @param session
	 * @throws Exception
	 */
	public static void updateApplicationEnv(String uuid, Map<String, String> envs, HttpSession session)
			throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("environment_json", envs);
		updateApplication(uuid, params, session);
	}

	/**
	 * 更新instance
	 * 
	 * @param uuid
	 * @param session
	 * @throws Exception
	 */
	public static void updateApplicationInstance(String uuid, Integer instances, HttpSession session) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("instances", instances);
		updateApplication(uuid, params, session);
	}

	/**
	 * 更新instance
	 * 
	 * @param uuid
	 * @param session
	 * @throws Exception
	 */
	public static void updateApplicationMem(String uuid, Integer memory, HttpSession session) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("memory", memory);
		updateApplication(uuid, params, session);
		stopApplication(uuid, session);
		startApplication(uuid, session);
	}

	/**
	 * 获取env.log
	 * 
	 * @throws Exception
	 */
	public static String getAppFile(String uuid, Integer index, String filePath, HttpSession session) throws Exception {
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		String urlPath = host + "/v2/apps/" + uuid + "/instances/" + index + "/files/" + filePath;
		return CloudFoundryClientUtil.doCCGet(urlPath, null, session);
	}

	/**
	 * 删除应用
	 * 
	 * @throws Exception
	 */
	public static void deleteApp(String uuid, HttpSession session) throws Exception {
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		String urlPath = host + "/v2/apps/" + uuid + "?recursive=true";
		CloudFoundryClientUtil.doCCDelete(urlPath, null, session);
	}

	/**
	 * 获取应用具体信息
	 * 
	 * @throws Exception
	 */
	public static Map<String, Object> getApp(String uuid, HttpSession session) throws Exception {
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		String urlPath = host + "/v2/apps/" + uuid + "/summary";
		String content = CloudFoundryClientUtil.doCCGet(urlPath, null, session);
		return JsonUtil.convertJsonToMap(content);
	}
	
	/**
	 * 获取应用环境变量v194
	 * 
	 * @throws Exception
	 */
	public static Map<String, Object> getAppSystemEnv(String uuid, HttpSession session) throws Exception {
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		String urlPath = host + "/v2/apps/" + uuid + "/env";
		String content = CloudFoundryClientUtil.doCCGet(urlPath, null, session);
		return JsonUtil.convertJsonToMap(content);
	}

	/**
	 * 获取环境变量
	 * 
	 * @param uuid
	 * @param session
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, String> getAppEnv(String uuid, HttpSession session) throws Exception {
		Map<String, Object> app = getApp(uuid, session);
		Object envs = app.get("environment_json");
		if (envs == null) {
			return new HashMap<String, String>();
		} else {
			return (Map<String, String>) envs;
		}
	}

	/**
	 * 获取应用状态
	 * 
	 * @param uuid
	 * @param session
	 * @return
	 * @throws Exception
	 */
	public static Map<String, Object> getAppState(String uuid, HttpSession session) throws Exception {
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		String urlPath = host + "/v2/apps/" + uuid + "/stats";
		String content = CloudFoundryClientUtil.doCCGet(urlPath, null, session);
		System.out.println("state:" + content);
		return JsonUtil.convertJsonToMap(content);
	}

	/**
	 * 获取实例具体信息（状态会和state不一样）
	 * 
	 * @param uuid
	 * @param session
	 * @return
	 * @throws Exception
	 */
	public static Map<String, Object> getAppInstances(String uuid, HttpSession session) throws Exception {
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		String urlPath = host + "/v2/apps/" + uuid + "/instances";
		String content;
		try {
			content = CloudFoundryClientUtil.doCCGet(urlPath, null, session);
			//System.out.println(content);
		} catch (Exception e) {
			if (e instanceof CloudFoundryApiException && ((CloudFoundryApiException) e).getErrorCode() == 400) {
				return null;
			} else {
				throw e;
			}
		}
		return JsonUtil.convertJsonToMap(content);
	}

	/**
	 * 获取应用route
	 * 
	 * @param appGuid
	 * @param session
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static List<Map<String, Object>> getAppRoutes(String appGuid, HttpSession session) throws Exception {
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		String urlPath = host + " /v2/apps/" + appGuid + "/routes";
		String content = CloudFoundryClientUtil.doCCGet(urlPath, null, session);
		Map<String, Object> data = JsonUtil.convertJsonToMap(content);
		List<Map<String, Object>> domains = (List<Map<String, Object>>) data.get("resources");
		String next_url = (String) data.get("next_url");
		while (next_url != null) {
			next_url = ApiCommonUtil.retriveAllPageResource(domains, next_url, session);
		}
		return domains;
	}

	/**
	 * 获取应用route
	 * 
	 * @param appGuid
	 * @param session
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static List<String> getAppRoutesList(String appGuid, HttpSession session) throws Exception {
		Map<String, Object> appCl = ApplicationApi.getApp(appGuid, session);
		List<Map<String, Object>> routesRes = (List<Map<String, Object>>) appCl.get("routes");
		List<String> routes = new ArrayList<String>();
		for (Map<String, Object> rRes : routesRes) {
			routes.add((String) rRes.get("host") + "." + ((Map<String, Object>) rRes.get("domain")).get("name"));
		}
		return routes;
	}

	/**
	 * 获取应用状态记录
	 * 
	 * @param appGuid
	 * @param session
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static List<Map<String, Object>> getAppEventList(String appGuid, HttpSession session) throws Exception {
		String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
		String urlPath = host + "/v2/events?q=actee:" + appGuid;
		String content = CloudFoundryClientUtil.doCCGet(urlPath, null, session);
		Map<String, Object> data = JsonUtil.convertJsonToMap(content);
		if ((int) data.get("total_results") == 0) {
			return null;
		}
		return (List<Map<String, Object>>) data.get("resources");
	}

	/**
	 * add app route
	 * 
	 * @param uuid
	 * @param session
	 * @return
	 * @throws Exception
	 */
	public static void addAppRoute(String appGuid, String org, String space, List<String> urls, HttpSession session)
			throws Exception {
		String orgGuid = UserApi.get_org_id(session, org);
		Map<String, String> domains = DomainApi.getDomainGuids(orgGuid, session);
		for (String uri : urls) {
			Map<String, String> uriInfo = new HashMap<String, String>(2);
			extractUriInfo(domains, uri, uriInfo);
			String domainGuid = domains.get(uriInfo.get("domainName"));
			String routeId = RouteApi.get_route_id(session, domainGuid, uriInfo.get("host"));
			if (StringUtil.isEmpty(routeId)) {
				String spaceGuid = UserApi.get_space_id(session, org, space);
				RouteApi.addRoute(uriInfo.get("host"), domainGuid, spaceGuid, session);
			}
			RouteApi.map_route_guid(session, domainGuid, uriInfo.get("host"), appGuid);
		}
	}

	/**
	 * 移除应用route
	 * 
	 * @param appGuid
	 * @param org
	 * @param space
	 * @param urls
	 * @param session
	 * @throws Exception
	 */
	public static void removeAppRoute(String appGuid, String org, String space, List<String> urls, HttpSession session)
			throws Exception {
		String orgGuid = UserApi.get_org_id(session, org);
		Map<String, String> domains = DomainApi.getDomainGuids(orgGuid, session);
		for (String uri : urls) {
			Map<String, String> uriInfo = new HashMap<String, String>(2);
			extractUriInfo(domains, uri, uriInfo);
			String domainGuid = domains.get(uriInfo.get("domainName"));
			RouteApi.unmap_route_guid(session, domainGuid, uriInfo.get("host"), appGuid);
		}
	}

	/**
	 * 应用绑定route时url处理
	 * 
	 * @param domains
	 * @param uri
	 * @param uriInfo
	 */
	protected static void extractUriInfo(Map<String, String> domains, String uri, Map<String, String> uriInfo) {
		URI newUri = URI.create(uri);
		String authority = newUri.getScheme() != null ? newUri.getAuthority() : newUri.getPath();
		for (String domain : domains.keySet()) {
			if (authority != null && authority.endsWith(domain)) {
				String previousDomain = uriInfo.get("domainName");
				if (previousDomain == null || domain.length() > previousDomain.length()) {
					// Favor most specific subdomains
					uriInfo.put("domainName", domain);
					if (domain.length() < authority.length()) {
						uriInfo.put("host", authority.substring(0, authority.indexOf(domain) - 1));
					} else if (domain.length() == authority.length()) {
						uriInfo.put("host", "");
					}
				}
			}
		}
		if (uriInfo.get("domainName") == null) {
			throw new IllegalArgumentException("Domain not found for URI " + uri);
		}
		if (uriInfo.get("host") == null) {
			throw new IllegalArgumentException("Invalid URI " + uri + " -- host not specified for domain "
					+ uriInfo.get("domainName"));
		}
	}
	
	public static void main(String[] args) throws Exception{
		CfApp app=new CfApp();
		app.setAppName("ewe");
		app.setUuid("e95eea71-5583-49fe-966e-dee67bfb7651");
		File file=new File("/home/yufangjiang/Downloads/example.war");
		ApplicationApi.uploadAppBit(app, file, null);
		
	}

}
